package com.xiongwei.dateAndTime;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;

/**
 * Java8引入了新的日期和时间API,它们是不变类,默认按ISO-8601标准格式化和解析
 * 使用LocalDateTime可以非常方便地对日期和时间进行计算
 * 使用isBefore和isAfter判断日期和时间的先后
 * 使用Duration和Period可以表示两个日期和时间的"区间间隔".
 *
 * @author XiongWei
 * @date 2021/1/29
 */
public class LocalDateTimeUse {

    /*
    新API修正了旧API的Month和Week
     */
    public static void main(String[] args) {
        LocalDate nowDate = LocalDate.now();
        LocalTime nowTime = LocalTime.now();
        LocalDateTime now = LocalDateTime.now();
        System.out.println(nowDate);
        System.out.println(nowTime);
        System.out.println(now);

        LocalDate d1 = LocalDate.of(2021, 1, 29);
        LocalTime t1 = LocalTime.of(15, 16, 17);
        //因为严格按照ISO-8601格式,所以将字符串转换为LocalDateTime就需要传入标准格式
        LocalDateTime dt = LocalDateTime.parse("2019-11-19T15:16:17");
        LocalDate d = LocalDate.parse("2019-11-19");
        LocalTime t = LocalTime.parse("15:16:17");

        //将非ISO8601格式的字符串解析成LocalDateTime
        // 自定义格式化:
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        System.out.println(dtf.format(LocalDateTime.now()));

        // 用自定义格式解析:
        LocalDateTime dt2 = LocalDateTime.parse("2019/11/30 15:16:17", dtf);
        System.out.println(dt2);

        //LocalDateTime提供了对日期和时间进行加减的简单的链式调用
        LocalDateTime dt3 = LocalDateTime.of(2019, 10, 26, 20, 30, 59);
        System.out.println(dt);
        // 加5天减3小时:
        LocalDateTime dt4 = dt3.plusDays(5).minusHours(3);
        System.out.println(dt2); // 2019-10-31T17:30:59
        // 减1月:
        LocalDateTime dt5 = dt4.minusMonths(1);
        System.out.println(dt3); // 2019-09-30T17:30:59
        //对日期和时间进行调整则使用withXxx()方法，
        dt5.withDayOfMonth(31).withMonth(9);

        /*
        LocalDateTime还有一个通用的with()方法允许我们做更复杂的运算
         */
        // 本月第一天0:00时刻:
        LocalDateTime firstDay = LocalDate.now().withDayOfMonth(1).atStartOfDay();
        System.out.println(firstDay);

        // 本月最后1天:
        LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        System.out.println(lastDay);

        // 下月第1天:
        LocalDate nextMonthFirstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfNextMonth());
        System.out.println(nextMonthFirstDay);

        // 本月第1个周一:
        LocalDate firstWeekday = LocalDate.now().with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
        System.out.println(firstWeekday);

        /*
        Duration表示两个时刻之间的时间间隔。另一个类似的Period表示两个日期之间的天数
         */
        LocalDateTime start = LocalDateTime.of(2019, 11, 19, 8, 15, 0);
        LocalDateTime end = LocalDateTime.of(2020, 1, 9, 19, 25, 30);
        Duration du = Duration.between(start, end);
        System.out.println(du); // PT1235H10M30S

        Period p = LocalDate.of(2019, 11, 19).until(LocalDate.of(2020, 1, 9));
        System.out.println(p); // P1M21D

        /*
        利用ofXxx()或者parse()方法也可以直接创建Duration：
         */
        Duration dd1 = Duration.ofHours(10); // 10 hours
        Duration dd2 = Duration.parse("P1DT2H3M"); // 1 day, 2 hours, 3 minutes
    }
}
